/*
 * ...
 */

package com.ruoyi.framework.web.entity;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;

import javax.validation.constraints.NotNull;
import javax.validation.groups.Default;
import java.io.Serializable;
import java.util.Date;

/**
 * 实体类基类
 *
 * @author 挺好的 2023年03月01日 下午 15:12
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public abstract class BaseEntity<ID extends Serializable> implements Serializable {

    private static final long serialVersionUID = 8482945444855874161L;


    /**
     * id属性名称
     */
    public static final String ID_PROPERTY_NAME = "id";

    /**
     * 创建时间
     */
    public static final String CREATE_DATE_PROPERTY_NAME = "createDate";

    /**
     * 修改时间
     */
    public static final String MODIFY_DATE_PROPERTY_NAME = "modifyDate";

    /**
     * 版本
     */
    public static final String VERSION_PROPERTY_NAME = "version";

    /**
     * 是否有效
     */
    public static final String IS_VALID_PROPERTY_NAME = "isValid";

    /**
     * 保存操作校验分组
     */
    public interface Save extends Default {

    }

    /**
     * 更新操作校验分组
     */
    public interface Update extends Default {

    }

    /**
     * 删除操作校验分组
     */
    public interface Delete extends Default {

    }

    /**
     * id
     */
    @NotNull (message = "ID不能为空", groups = Update.class)
    private ID id;

    /**
     * 创建时间
     */
    private Date createDate;

    /**
     * 修改时间
     */
    private Date modifyDate;

    /**
     * 版本号
     */
    private Long version;

    /**
     * 是否有效
     */
    private Boolean isValid;

    /**
     * 是否是新的对象
     *
     * @return 当id == null 的时候，返回true，否则返回false
     */
    public boolean isNew () {
        return this.getId() == null;
    }

    /**
     * 重写equals，只根据ID来判断是否相等
     *
     * @param obj
     *
     * @return
     */
    @Override
    public boolean equals (Object obj) {
        if (obj == null) {
            return false;
        }

        if (this == obj) {
            return true;
        }

        if (!BaseEntity.class.isAssignableFrom(obj.getClass())) {
            return false;
        }

        BaseEntity <?> other = (BaseEntity <?>) obj;

        if (this.getId() == null) {
            return false;
        }

        return this.getId().equals(other.getId());
    }

    /**
     * hashCode
     *
     * @return
     */
    @Override
    public int hashCode () {
        int hashCode = 17;
        hashCode += this.getId() != null ? this.getId().hashCode() * 31 : 0;
        return hashCode;
    }

    /**
     * 保存之前的操作
     */
    public void prePersist () {
        Date now = new Date();
        this.setCreateDate(now);
        this.setModifyDate(now);
        this.setIsValid(true);
        this.setVersion(0L);
    }

    /**
     * 更新之前的操作
     */
    public void preUpdate () {
        this.setModifyDate(new Date());
    }
}
